from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_TABLE_ALIGNMENT, WD_ALIGN_VERTICAL
from docx import Document
from docx.shared import Pt, Inches
from docx.oxml.ns import qn
from docx.shared import RGBColor
from time import strftime, localtime
import json


# author 曹一鸣
class pdf():
    def __init__(self, time, baseline_info_result,baseline_info, run_once, patch_info):

        # 获取报告生成时间
        self.__current_time = strftime('%Y-%m-%d %H:%M:%S', localtime())
        self.__run_once = run_once
        self.__patch_info = patch_info
        self.__baseline_info = baseline_info
        self.__time = time
        self.__baseline_info_result = baseline_info_result

    def main(self):

        document = Document()

        # 增大左右页边距，使得每一行可以显示更多的文字。注意此操作必须放置在图片之类的居中操作之前，不然是按照的原本的页面居中。
        section = document.sections[0]
        section.left_margin = Pt(45)
        section.right_margin = Pt(45)

        # 全局设置正文字体为宋体
        document.styles['Normal'].font.name = u'宋体'
        document.styles['Normal']._element.rPr.rFonts.set(
            qn('w:eastAsia'), u'宋体')

        # 全局设置字体为黑色
        document.styles['Normal'].font.color.rgb = RGBColor(0x00, 0x00, 0x00)

        # 全局默认字号设置为14(四号字体)
        document.styles['Normal'].font.size = Pt(14)

        # 添加标题，并设置级别，范围：0 至 9，默认为1
        document.add_paragraph('')
        document.add_paragraph('')
        document.add_paragraph('')
        document.add_paragraph('')
        p = document.add_paragraph()
        temp = p.add_run('基线扫描汇总报告')
        font = temp.font
        p.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
        font.size = Pt(26)
        temp.font.bold = True
        document.add_paragraph('')
        document.add_paragraph('')
        document.add_paragraph('')
        document.add_paragraph('')
        document.add_paragraph('')
        document.add_paragraph('')

        p = document.add_paragraph()
        font = p.add_run('报表生成时间: %s' % (self.__current_time)).font
        font.size = Pt(18)
        p.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
        document.add_page_break()  # 添加分页符，免得表格被分成了两页来展示

        # 1 基线检查
        p = document.add_paragraph()
        run = p.add_run('一、安全基线检查')
        run.font.bold = True  # 加粗
        p = document.add_paragraph()
        total_baseline_cnt = 161
        # false_baseline_cnt = 59
        # run = p.add_run('总计完成%d条策略的检查，其中%d条策略不符合要求。'%(total_baseline_cnt, false_baseline_cnt))
        run = p.add_run('总计完成%d条策略的检查' % (total_baseline_cnt))
        run.font.bold = True  # 加粗

       

        paragraph = document.add_paragraph('安全详情')
        paragraph.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
        paragraph.paragraph_format.keep_with_next = True  # 保证表格的索引要跟着表格走，这两者必须显示在同一页
        # 添加表格：一行4列
        table = document.add_table(
            rows=1, cols=5, style='Medium Shading 1 Accent 5')
        table.autofit = True  # 让表格自适应调整宽度
        table.alignment = WD_TABLE_ALIGNMENT.CENTER  # 表格整体居中
        # 获取第一行的单元格列表
        hdr_cells = table.rows[0].cells
        # 下面三行设置上面第一行的七个单元格的文本值
        hdr_cells[0].text = '服务风险项'
        hdr_cells[1].text = '系统配置风险项'
        hdr_cells[2].text = '权限配置风险项'
        hdr_cells[3].text = '注册风险项'
        hdr_cells[4].text = '风险等级'

        if self.__baseline_info_result["securityCode"] == 0 :
            risk = "低风险"
        elif  self.__baseline_info_result["securityCode"] == 1:
            risk = "中风险"
        else:
            risk = "高风险"
        # 表格添加行，并返回行所在的单元格列表
        row_cells = table.add_row().cells
        row_cells[0].text = str(self.__baseline_info_result["services"])
        row_cells[1].text = str(self.__baseline_info_result["systemAccess"])
        row_cells[2].text = str(self.__baseline_info_result["privilegeRights"])
        row_cells[3].text = str(self.__baseline_info_result["registryValue"])
        row_cells[4].text = risk
        # 让表格里的文字全都居中显示
        for r in range(2):  # 加上标题行，总共四行文字
            for c in range(5):
                table.cell(
                    r, c).paragraphs[0].paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER  # 水平方向居中
                # 垂直方向居中
                table.cell(r, c).vertical_alignment = WD_ALIGN_VERTICAL.CENTER
        # 把表格里的所有文字调小到12号
        for row in table.rows:
            for cell in row.cells:
                paragraphs = cell.paragraphs
                for paragraph in paragraphs:
                    for run in paragraph.runs:
                        font = run.font
                        font.size = Pt(12)

        # 1-2 表1:未满足配置要求的安全策略详情
        document.add_page_break()
        paragraph = document.add_paragraph('表1.未满足配置要求的安全策略详情')
        paragraph.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
        paragraph.paragraph_format.keep_with_next = True  # 保证表格的索引要跟着表格走，这两者必须显示在同一页
        # 添加表格：一行4列
        table = document.add_table(
            rows=1, cols=5, style='Medium Shading 1 Accent 5')
        table.autofit = True  # 让表格自适应调整宽度
        table.alignment = WD_TABLE_ALIGNMENT.CENTER  # 表格整体居中
        # 获取第一行的单元格列表
        hdr_cells = table.rows[0].cells
        # 下面三行设置上面第一行的七个单元格的文本值
        hdr_cells[0].text = '策略名称'
        hdr_cells[1].text = '当前值'
        hdr_cells[2].text = '检查结果'
        hdr_cells[3].text = '加固策略'
        hdr_cells[4].text = '检测类型'

        # print(self.__baseline_info)
        for v1, v2, v3, v4, v5, v6, v7, v8, v9 in self.__baseline_info:
            # 表格添加行，并返回行所在的单元格列表
            row_cells = table.add_row().cells
            row_cells[0].text = str(v2)
            row_cells[1].text = str(v3)
            row_cells[2].text = str(v5)
            row_cells[3].text = str(v7)
            row_cells[4].text = str(v8)
        # 让表格里的文字全都居中显示
        for r in range(162):  # 加上标题行，总共四行文字
            for c in range(5):
                table.cell(
                    r, c).paragraphs[0].paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER  # 水平方向居中
                # 垂直方向居中
                table.cell(r, c).vertical_alignment = WD_ALIGN_VERTICAL.CENTER
        # 把表格里的所有文字调小到12号
        for row in table.rows:
            for cell in row.cells:
                paragraphs = cell.paragraphs
                for paragraph in paragraphs:
                    for run in paragraph.runs:
                        font = run.font
                        font.size = Pt(12)

        # 2 自启动项检查
        p = document.add_paragraph()
        p = document.add_paragraph()
        run = p.add_run('二、开机自启动项检查')
        run.font.bold = True  # 加粗
        p = document.add_paragraph()
        total_auto_cnt = len(self.__run_once)
        run = p.add_run('总计%d条开机自启动项，详细信息如下表。' % (total_auto_cnt))
        run.font.bold = True  # 加粗

        # 2-1 表2:开机自启动项
        paragraph = document.add_paragraph('表2.开机自启动项详情')
        paragraph.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
        paragraph.paragraph_format.keep_with_next = True  # 保证表格的索引要跟着表格走，这两者必须显示在同一页
        # 添加表格：一行2列
        table = document.add_table(
            rows=1, cols=2, style='Medium Shading 1 Accent 5')
        table.autofit = True  # 让表格自适应调整宽度
        table.alignment = WD_TABLE_ALIGNMENT.CENTER  # 表格整体居中
        # 获取第一行的单元格列表
        hdr_cells = table.rows[0].cells
        # 下面三行设置上面第一行的七个单元格的文本值
        hdr_cells[0].text = '名称'
        hdr_cells[1].text = '路径'

        for v1, v2 in self.__run_once.items():
            # 表格添加行，并返回行所在的单元格列表
            row_cells = table.add_row().cells
            row_cells[0].text = str(v1)
            row_cells[1].text = str(v2)

        # 让表格里的文字全都居中显示
        for r in range(total_auto_cnt+1):  # 加上标题行，总共四行文字
            for c in range(2):
                table.cell(
                    r, c).paragraphs[0].paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER  # 水平方向居中
                # 垂直方向居中
                table.cell(r, c).vertical_alignment = WD_ALIGN_VERTICAL.CENTER
        # 把表格里的所有文字调小到12号
        for row in table.rows:
            for cell in row.cells:
                paragraphs = cell.paragraphs
                for paragraph in paragraphs:
                    for run in paragraph.runs:
                        font = run.font
                        font.size = Pt(12)

        # 3 补丁信息
        p = document.add_paragraph()
        p = document.add_paragraph()
        run = p.add_run('三、补丁信息')
        run.font.bold = True  # 加粗
        p = document.add_paragraph()
        total_patch_cnt = len(self.__patch_info)
        run = p.add_run('共检测到了%d个补丁，详细信息如下表。' % (total_patch_cnt))
        run.font.bold = True  # 加粗

        # 3-1 表1:未满足配置要求的安全策略详情
        paragraph = document.add_paragraph('表3.补丁信息详情')
        paragraph.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
        paragraph.paragraph_format.keep_with_next = True  # 保证表格的索引要跟着表格走，这两者必须显示在同一页
        # 添加表格：一行3列
        table = document.add_table(
            rows=1, cols=3, style='Medium Shading 1 Accent 5')
        table.autofit = True  # 让表格自适应调整宽度
        table.alignment = WD_TABLE_ALIGNMENT.CENTER  # 表格整体居中
        # 获取第一行的单元格列表
        hdr_cells = table.rows[0].cells
        # 下面三行设置上面第一行的七个单元格的文本值
        hdr_cells[0].text = 'ID'
        hdr_cells[1].text = '安装时间'
        hdr_cells[2].text = '描述'

        for item in self.__patch_info:
            ls = list(item.values())
            # 表格添加行，并返回行所在的单元格列表
            row_cells = table.add_row().cells
            row_cells[0].text = ls[0]
            row_cells[1].text = ls[1]
            row_cells[2].text = ls[2]

        # 让表格里的文字全都居中显示
        for r in range(total_patch_cnt+1):  # 加上标题行，总共四行文字
            for c in range(3):
                table.cell(
                    r, c).paragraphs[0].paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER  # 水平方向居中
                # 垂直方向居中
                table.cell(r, c).vertical_alignment = WD_ALIGN_VERTICAL.CENTER
        # 把表格里的所有文字调小到12号
        for row in table.rows:
            for cell in row.cells:
                paragraphs = cell.paragraphs
                for paragraph in paragraphs:
                    for run in paragraph.runs:
                        font = run.font
                        font.size = Pt(12)

        # 保存.docx文档
        document.save(self.__time+".docx")


if __name__ == "__main__":
    main()
    # transition()
